Skip to content

fix(examples/ts-code-mode-web): persist reports across reloads#515

Open
arnthors wants to merge 1 commit intoTanStack:mainfrom
arnthors:pr/fix-use-persisted-reports
Open

fix(examples/ts-code-mode-web): persist reports across reloads#515
arnthors wants to merge 1 commit intoTanStack:mainfrom
arnthors:pr/fix-use-persisted-reports

Conversation

@arnthors
Copy link
Copy Markdown

@arnthors arnthors commented Apr 29, 2026

🎯 Changes

The debounced save in usePersistedReports is created once and cached in a ref, capturing the initial empty reports Map and null activeReportId from the first effect run. Subsequent renders re-fire the effect but reuse the cached closure, so every localStorage.setItem writes the empty initial state — the UI shows populated reports while localStorage stays empty, and reports vanish on reload.

  • Recreate the debounced save each effect run; cleanup cancels the in-flight debounce on each render so debouncing semantics are preserved.
  • Drop the now-unused useRef import and saveRef declaration.

Repro on main

  1. pnpm dev in examples/ts-code-mode-web, open /reporting-agent
  2. DevTools → Application → Local Storage → http://localhost:3001
  3. Generate a report — tanstack-ai-reports stays {"reports":[],"activeReportId":null,"version":1} despite the populated UI; reload → report disappears

After this PR the value contains the full serialized report and survives reload.

Note on the missing contributing guide

The repo currently has no CONTRIBUTING.md — both README.md and .github/pull_request_template.md link to one that 404s. Filed #514 with details. As a substitute, I followed TanStack/query's CONTRIBUTING.md, adapted for this repo:

  • pnpm 10 + pnpm build:all
  • pnpm run test:pr (the nx-based per-PR entrypoint) ✅, all tasks pass
  • Ran on Node 22.13.1 rather than the .nvmrc-pinned 24.8.0
  • No changeset since the affected example is "private": true (pnpm changeset status confirms no packages to bump)
  • E2E coverage not added — there is no existing test infra for this example's persistence layer; happy to add one if maintainers want

✅ Checklist

  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release). The ts-code-mode-web example is "private": true and not published.

Summary by CodeRabbit

  • Bug Fixes
    • Improved the reliability of report saving to local storage by refining how debounced save operations are managed and cleaned up during component lifecycle changes.

The debounced save in usePersistedReports was created once and cached
in a ref, capturing the initial empty 'reports' Map and null
'activeReportId' from the first effect run. Subsequent renders re-fired
the effect but reused the cached closure, so every localStorage.setItem
wrote the empty initial state.

Recreate the debounced save each effect run; the cleanup cancels the
in-flight debounce on each render so debouncing semantics are preserved.

Repro:
1. Run examples/ts-code-mode-web (pnpm dev) and open /reporting-agent
2. Generate a report
3. DevTools > Application > Local Storage > 'tanstack-ai-reports' shows
   {"reports":[],"activeReportId":null,"version":1} despite the
   populated UI; reload makes the report disappear
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

A React hook's localStorage persistence effect was refactored to create a fresh debounced save function on each dependency change instead of reusing a stored reference, with immediate invocation and targeted cleanup per debounced instance.

Changes

Cohort / File(s) Summary
localStorage Debouncing Refactor
examples/ts-code-mode-web/src/lib/reports/use-persisted-reports.ts
Modified effect to generate a new debounced save function on each hydration or dependency change, invoke it immediately, and cancel that specific instance during cleanup rather than reusing a ref-stored debouncer across renders.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop, skip, and debounce with care!
No refs to hoard or reuse there—
Fresh functions bloom with every change,
Cleanup whispers cancel's range.
localStorage saved, pristine and fair!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main fix: persisting reports across reloads in the usePersistedReports hook.
Description check ✅ Passed The description provides comprehensive context: explains the bug, describes the fix, includes reproduction steps, and thoroughly addresses the checklist despite repository documentation gaps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/ts-code-mode-web/src/lib/reports/use-persisted-reports.ts`:
- Line 3: The import member order in the React import in
use-persisted-reports.ts is not alphabetized and violates sort-imports; reorder
the named imports in the statement "import { useState, useEffect, useCallback }
from 'react'" to alphabetic order (useCallback, useEffect, useState) so the
import line follows ESLint's sort-imports rule.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 45c9e994-3a33-4f7a-ac5a-913e79ae1885

📥 Commits

Reviewing files that changed from the base of the PR and between ff33855 and 14f141b.

📒 Files selected for processing (1)
  • examples/ts-code-mode-web/src/lib/reports/use-persisted-reports.ts

'use client'

import { useState, useEffect, useCallback, useRef } from 'react'
import { useState, useEffect, useCallback } from 'react'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix import member order to satisfy ESLint.

Line 3 currently violates sort-imports (members should be alphabetized), which can fail lint checks.

Suggested fix
-import { useState, useEffect, useCallback } from 'react'
+import { useCallback, useEffect, useState } from 'react'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useState, useEffect, useCallback } from 'react'
import { useCallback, useEffect, useState } from 'react'
🧰 Tools
🪛 ESLint

[error] 3-3: Member 'useEffect' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/ts-code-mode-web/src/lib/reports/use-persisted-reports.ts` at line
3, The import member order in the React import in use-persisted-reports.ts is
not alphabetized and violates sort-imports; reorder the named imports in the
statement "import { useState, useEffect, useCallback } from 'react'" to
alphabetic order (useCallback, useEffect, useState) so the import line follows
ESLint's sort-imports rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant